/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.sys.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.BasePage;
import com.thinkgem.jeesite.common.service.ServiceException;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.utils.excel.ExportExcel;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.frame.pm.PmConstants;
import com.thinkgem.jeesite.frame.pm.entity.PmDataDictItem;
import com.thinkgem.jeesite.frame.pm.utils.PmDataDictUtils;
import com.thinkgem.jeesite.modules.sys.SysConstants;
import com.thinkgem.jeesite.modules.sys.entity.SysRole;
import com.thinkgem.jeesite.modules.sys.entity.SysUser;
import com.thinkgem.jeesite.modules.sys.service.SysUserService;
import com.thinkgem.jeesite.modules.sys.utils.PasswordUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * 用户Controller
 *
 * @author kongxiangsheng
 * @version 2013-8-29
 */
@Controller
@RequestMapping(value = "${adminPath}/sys/sysUser")
public class SysUserController extends BaseController {
    @Autowired
    private SysUserService sysUserService;

    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = {"index"})
    public String index(SysUser sysUser, Model model) {
        return "modules/sys/SysUser/index";
    }

    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = {"list", ""})
    public String list(SysUser sysUser, HttpServletRequest request, HttpServletResponse response, Model model) {
        BasePage<SysUser> page = new BasePage<SysUser>(request, response);
        sysUserService.selectUserPage(page, sysUser);
        model.addAttribute("page", page);
        return "modules/sys/SysUser/list";
    }

    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = "form")
    public String form(SysUser sysUser, Model model) {
        if (StringUtils.isNotBlank(sysUser.getId())) {
            sysUser = sysUserService.get(sysUser.getId());
        }
        if (StringUtils.isBlank(sysUser.getCompanyId())) {
            sysUser.setCompanyId(UserUtils.getUser().getCompanyId());
        }
        if (StringUtils.isBlank(sysUser.getOfficeId())) {
            sysUser.setOfficeId(UserUtils.getUser().getOfficeId());
        }
        model.addAttribute("sysUser", sysUser);
        model.addAttribute("allRoles", UserUtils.getRoleList());
        return "modules/sys/SysUser/form";
    }

    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "save")
    public String save(SysUser sysUser, HttpServletRequest request, Model model, RedirectAttributes redirectAttributes) {
        // 修正引用赋值问题，不知道为何，Office引用的一个实例地址，修改了一个，另外一个跟着修改。
        sysUser.setOfficeId(request.getParameter("officeId"));
        // 如果新密码为空，则不更换密码
        if (StringUtils.isNotBlank(sysUser.getNewPassword())) {
            sysUser.setPassword(PasswordUtils.entryptPassword(sysUser.getNewPassword()));
        }
        if (!beanValidator(model, sysUser)) {
            return form(sysUser, model);
        }
        if (!"true".equals(checkLoginName(sysUser.getOldLoginName(), sysUser.getLoginName()))) {
            addMessage(model, "保存用户'" + sysUser.getLoginName() + "'失败，登录名已存在");
            return form(sysUser, model);
        }
        // 角色数据有效性验证，过滤不在授权内的角色
        List<SysRole> roleList = Lists.newArrayList();
        List<String> roleIdList = sysUser.getRoleIdList();
        for (SysRole r : UserUtils.getRoleList()) {
            if (roleIdList.contains(r.getId())) {
                roleList.add(r);
            }
        }
        sysUser.setRoleList(roleList);

        // 保存用户信息
        sysUserService.saveUser(sysUser);

        addMessage(redirectAttributes, "保存用户'" + sysUser.getLoginName() + "'成功");
        return "redirect:" + adminPath + "/sys/sysUser/list?repage";
    }

    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "delete")
    public String delete(SysUser sysUser, RedirectAttributes redirectAttributes) {
        if (UserUtils.getCurrentUserId().equals(sysUser.getId())) {
            addMessage(redirectAttributes, "删除用户失败, 不允许删除当前用户");
        } else if (SysUser.isAdmin(sysUser.getId())) {
            addMessage(redirectAttributes, "删除用户失败, 不允许删除超级管理员用户");
        } else {
            sysUserService.deleteUser(sysUser);
            addMessage(redirectAttributes, "删除用户成功");
        }
        return "redirect:" + adminPath + "/sys/sysUser/list?repage";
    }

    /**
     * 导出用户数据
     *
     * @param sysUser
     * @param request
     * @param response
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = "export", method = RequestMethod.POST)
    public String exportFile(SysUser sysUser, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        try {
            String fileName = "用户数据" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";

            QueryWrapper queryWrapper = new QueryWrapper<SysUser>(sysUser);
            List<SysUser> sysUserList = sysUserService.list(queryWrapper);
            new ExportExcel("用户数据", SysUser.class).setDataList(sysUserList).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            addMessage(redirectAttributes, "导出用户失败！失败信息：" + e.getMessage());
        }
        return "redirect:" + adminPath + "/sys/sysUser/list?repage";
    }

    /**
     * 验证登录名是否有效
     *
     * @param oldLoginName
     * @param loginName
     * @return
     */
    @ResponseBody
    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "checkLoginName")
    public String checkLoginName(String oldLoginName, String loginName) {
        if (loginName != null && loginName.equals(oldLoginName)) {
            return "true";
        } else if (loginName != null && UserUtils.getByLoginName(loginName) == null) {
            return "true";
        }
        return "false";
    }

    /**
     * 用户信息显示及保存
     *
     * @param sysUser
     * @param model
     * @return
     */
    @RequiresPermissions("user")
    @RequestMapping(value = "info")
    public String info(SysUser sysUser, HttpServletResponse response, Model model) {
        SysUser currentUser = UserUtils.getUser();
        if (StringUtils.isNotBlank(sysUser.getName())) {
            currentUser.setEmail(sysUser.getEmail());
            currentUser.setPhone(sysUser.getPhone());
            currentUser.setMobile(sysUser.getMobile());
            currentUser.setRemarks(sysUser.getRemarks());
            currentUser.setPhoto(sysUser.getPhoto());
            sysUserService.saveUser(currentUser);
            model.addAttribute("message", "保存用户信息成功");
        }
        model.addAttribute("sysUser", currentUser);
        //修改Global 没有私有构造函数，实现懒汉式单例模式.在第一次调用的时候实例化自己！
        model.addAttribute("Global", Global.getInstance());
        return "modules/sys/SysUser/userInfo";
    }

    /**
     * 返回用户信息
     *
     * @return
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "infoData")
    public SysUser infoData() {
        return UserUtils.getUser();
    }

    /**
     * 修改个人用户密码
     *
     * @param oldPassword
     * @param newPassword
     * @param model
     * @return
     */
    @RequiresPermissions("user")
    @RequestMapping(value = "modifyPwd")
    public String modifyPwd(String oldPassword, String newPassword, Model model) {
        SysUser sysUser = UserUtils.getUser();
        if (StringUtils.isNotBlank(oldPassword) && StringUtils.isNotBlank(newPassword)) {
            if (PasswordUtils.validatePassword(oldPassword, sysUser.getPassword())) {
                sysUser.setPassword(PasswordUtils.entryptPassword(newPassword));
                sysUserService.saveUser(sysUser);
                model.addAttribute("message", "修改密码成功");
            } else {
                model.addAttribute("message", "修改密码失败，旧密码错误");
            }
        }
        model.addAttribute("sysUser", sysUser);
        return "modules/sys/SysUser/modifyPassword";
    }

    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "treeValue")
    public String treeValue(@RequestParam(required = true) String id, HttpServletResponse response) {
        String[] ids = id.split(",");
        List<String> nameList = Lists.newArrayList();
        for (String userId : ids) {
            SysUser sysUser = UserUtils.get(userId);
            if (null != sysUser) {
                nameList.add(sysUser.getName());
            }
        }
        String sysUserName = StringUtils.join(nameList, ",");
        return sysUserName;
    }

    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "treeData")
    public List<Map<String, Object>> treeData(@RequestParam(required = false) String officeId, HttpServletResponse response) {
        List<Map<String, Object>> mapList = Lists.newArrayList();
        List<SysUser> list = sysUserService.findUserByOfficeId(officeId);
        for (int i = 0; i < list.size(); i++) {
            SysUser e = list.get(i);
            Map<String, Object> map = Maps.newHashMap();
            map.put("id", "u_" + e.getId());
            map.put("pId", officeId);
            map.put("name", StringUtils.replace(e.getName(), " ", ""));
            mapList.add(map);
        }
        return mapList;
    }

    /**
     * 指定用户类型的用户信息查询
     *
     * @param sysUser
     * @param request
     * @param response
     * @param model
     * @return
     */
    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = {"busiList"})
    public String busiList(SysUser sysUser, HttpServletRequest request, HttpServletResponse response, Model model) {
        if (StringUtils.isBlank(sysUser.getUserType())) {
            throw new ServiceException("传入的用户类型为空！");
        }

        // 用户类型字典条目
        PmDataDictItem userTypeDictItem = PmDataDictUtils.getDataDictItem(PmConstants.DICT_SYS_USER_TYPE, sysUser.getUserType());

        BasePage<SysUser> page = new BasePage<SysUser>(request, response);
        sysUserService.selectUserPage(page, sysUser);
        model.addAttribute("page", page);
        model.addAttribute("userTypeDictItem", userTypeDictItem);
        return "modules/sys/SysUser/busiList";
    }

    /**
     * 指定用户类型的用户信息查看
     *
     * @param sysUser
     * @param model
     * @return
     */
    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = "busiForm")
    public String busiForm(SysUser sysUser, Model model) {
        if (StringUtils.isBlank(sysUser.getCompanyId())) {
            sysUser.setCompanyId(UserUtils.getUser().getCompanyId());
        }
        if (StringUtils.isBlank(sysUser.getOfficeId())) {
            sysUser.setOfficeId(UserUtils.getUser().getOfficeId());
        }
        // 用户类型字典条目
        PmDataDictItem userTypeDictItem = PmDataDictUtils.getDataDictItem(PmConstants.DICT_SYS_USER_TYPE, sysUser.getUserType());

        model.addAttribute("sysUser", sysUser);
        model.addAttribute("userTypeDictItem", userTypeDictItem);
        model.addAttribute("allRoles", UserUtils.getRoleList());
        return "modules/sys/SysUser/busiForm";
    }

    /**
     * 指定用户类型的用户信息保存
     *
     * @param sysUser
     * @param request
     * @param model
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "busiSave")
    public String busiSave(SysUser sysUser, HttpServletRequest request, Model model, RedirectAttributes redirectAttributes) {
        // 修正引用赋值问题，不知道为何，Office引用的一个实例地址，修改了一个，另外一个跟着修改。
        sysUser.setOfficeId(request.getParameter("officeId"));
        // 如果新密码为空，则不更换密码
        if (StringUtils.isNotBlank(sysUser.getNewPassword())) {
            sysUser.setPassword(PasswordUtils.entryptPassword(sysUser.getNewPassword()));
        }
        if (!beanValidator(model, sysUser)) {
            return busiForm(sysUser, model);
        }
        if (!"true".equals(checkLoginName(sysUser.getOldLoginName(), sysUser.getLoginName()))) {
            addMessage(model, "保存用户'" + sysUser.getLoginName() + "'失败，登录名已存在");
            return busiForm(sysUser, model);
        }
        // 角色数据有效性验证，过滤不在授权内的角色
        List<SysRole> roleList = Lists.newArrayList();
        List<String> roleIdList = sysUser.getRoleIdList();
        for (SysRole r : UserUtils.getRoleList()) {
            if (roleIdList.contains(r.getId())) {
                roleList.add(r);
            }
        }
        sysUser.setRoleList(roleList);

        // 保存用户信息
        sysUserService.saveUser(sysUser);

        addMessage(redirectAttributes, "保存用户'" + sysUser.getLoginName() + "'成功");
        return "redirect:" + adminPath + "/sys/sysUser/busiList?userType=" + sysUser.getUserType() + "&&repage";
    }

    /**
     * 指定用户类型的用户信息删除
     *
     * @param sysUser
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "busiDelete")
    public String busiDelete(SysUser sysUser, RedirectAttributes redirectAttributes) {
        if (UserUtils.getCurrentUserId().equals(sysUser.getId())) {
            addMessage(redirectAttributes, "删除用户失败, 不允许删除当前用户");
        } else if (SysUser.isAdmin(sysUser.getId())) {
            addMessage(redirectAttributes, "删除用户失败, 不允许删除超级管理员用户");
        } else {
            sysUserService.deleteUser(sysUser);
            addMessage(redirectAttributes, "删除用户成功");
        }
        return "redirect:" + adminPath + "/sys/sysUser/busiList?userType=" + sysUser.getUserType() + "&&repage";
    }

    /**
     * 会员信息查看
     *
     * @param sysUser
     * @param request
     * @param response
     * @param model
     * @return
     */
    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = "wechatList")
    public String wechatList(SysUser sysUser, HttpServletRequest request, HttpServletResponse response, Model model) {
        // 用户类型字典条目
        PmDataDictItem userTypeDictItem = PmDataDictUtils.getDataDictItem(PmConstants.DICT_SYS_USER_TYPE, SysConstants.UserType.WECHAT);

        // 用户类型是普通微信会员
        sysUser.setUserType(SysConstants.UserType.WECHAT);

        // 查询
        BasePage<SysUser> page = new BasePage<SysUser>(request, response);
        sysUserService.selectWechatPage(page, sysUser);
        model.addAttribute("page", page);
        model.addAttribute("userTypeDictItem", userTypeDictItem);
        return "modules/sys/SysUser/wechatList";
    }

    /**
     * 指定用户类型的用户信息查看
     *
     * @param sysUser
     * @param model
     * @return
     */
    @RequiresPermissions("sys:sysUser:view")
    @RequestMapping(value = "wechatForm")
    public String wechatForm(SysUser sysUser, Model model) {
        // 用户类型字典条目
        PmDataDictItem userTypeDictItem = PmDataDictUtils.getDataDictItem(PmConstants.DICT_SYS_USER_TYPE, sysUser.getUserType());

        model.addAttribute("sysUser", sysUser);
        model.addAttribute("userTypeDictItem", userTypeDictItem);
        return "modules/sys/SysUser/wechatForm";
    }

    /**
     * 指定用户类型的用户信息保存
     *
     * @param sysUser
     * @param request
     * @param model
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "wechatSave")
    public String wechatSave(SysUser sysUser, HttpServletRequest request, Model model, RedirectAttributes redirectAttributes) {
        if (!beanValidator(model, sysUser)) {
            return wechatForm(sysUser, model);
        }

        // 保存用户信息
        sysUserService.saveUser(sysUser);

        addMessage(redirectAttributes, "保存用户'" + sysUser.getLoginName() + "'成功");
        return "redirect:" + adminPath + "/sys/sysUser/wechatList?&&repage";
    }

    /**
     * 禁止会员登录
     *
     * @param userId
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "denyWechatLogin")
    public String denyWechatLogin(String userId, RedirectAttributes redirectAttributes) {
        if (StringUtils.isBlank(userId)) {
            addMessage(redirectAttributes, "传入参数为空！");
        }
        // 修改登录状态
        SysUser sysUser = UserUtils.get(userId);
        sysUser.setLoginFlag("N");
        sysUserService.saveUser(sysUser);
        // 返回
        addMessage(redirectAttributes, "已禁止该会员登录系统");
        return "redirect:" + adminPath + "/sys/sysUser/wechatList?&&repage";
    }

    /**
     * 允许会员登录
     *
     * @param userId
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("sys:sysUser:edit")
    @RequestMapping(value = "allowWechatLogin")
    public String allowWechatLogin(String userId, RedirectAttributes redirectAttributes) {
        if (StringUtils.isBlank(userId)) {
            addMessage(redirectAttributes, "传入参数为空！");
        }
        // 修改登录状态
        SysUser sysUser = UserUtils.get(userId);
        sysUser.setLoginFlag("Y");
        sysUserService.saveUser(sysUser);
        // 返回
        addMessage(redirectAttributes, "已允许该会员登录系统");
        return "redirect:" + adminPath + "/sys/sysUser/wechatList?&&repage";
    }
}
